! ******************************************************************************
! Copyright (C) 2023-2033 Zhejiang University
!
! This program is free software: you can redistribute it and/or modify
! it under the terms of the GNU General Public License as published by
! the Free Software Foundation, either version 3 of the License, or
! (at your option) any later version.
!
! This program is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! GNU General Public License for more details.
!
! You should have received a copy of the GNU General Public License
! along with this program. If not, see <http://www.gnu.org/licenses/>.
! ******************************************************************************

! ******************************************************************************
!                             LANT Project
! The LANT (Laboratory Astrophysical Numerical Toolkits) project aims to develop
! numerical simulation codes for Laboratory Astrophysical research. This project
! plans to develop radiation hydrodynamics code, kinetics code, hybrid code and
! experimental diagnostics code. The leader of the LANT project is Jin-Long Jiao 
! who is a member both of the Zhejiang Institute of Modern Physics and the Inst-
! -itute of Astronomy at the Zhejiang University.
!
! If you have questions, please contact the author with: jiao.jl@zju.edu.cn
! Date: Oct. 20, 2023
! ******************************************************************************

! ******************************************************************************
!                             LANT-Hybrid Code
! The LANT-Hybrid code is a hybrid code in the LANT project. In this code, all 
! the ions are treated kinetically, the electrons are assumed to be an massless 
! and quasi-neutral fluid, and the electromagnetic fields are calculated in the 
! low-frequency approximation. The magnetic field of the ion-Weibel instability
! are included in this code by solving the ion current screening (ICS) equation.
! The Hybrid2D is a parallel and 2D version and is written by Jin-Long Jiao.
!
! If you have questions, please contact the author with: jiao.jl@zju.edu.cn.
! Date: Oct. 20, 2023
! ******************************************************************************

! ******************************************************************************
! Main Program
! ******************************************************************************

program Hybrid2D
    use Setup
    use Input
    use Initialization
    use Boundary
    use Communication
    use Physics
    use Output
    implicit none

! *******************************************************************
! Initialization
! *******************************************************************

    call mpi_init(ierr)                                      ! MPI.mod
    call mpi_comm_rank(mpi_comm_world,Myid,ierr)             ! MPI.mod
    call mpi_comm_size(mpi_comm_world,TotalProcessors,ierr)  ! MPI.mod

    call setInput()             ! Initialization.F90

    if(UseTime) call recordStartTime()    ! Time.F90

    if(TotalProcessors/=ppx*ppy)then
        write(*,*)"Your entered processor number is mismatch with ppx*ppy !"
        call mpi_finalize(ierr)
        stop
    end if

    call setDimensionless()     ! Initialization.F90
    if(myid==1)then
        write(*,"(/,A15,$)") "[Omega_p]","[Omega_g]","[SkinDepth]","[lambda_De]"
        write(*,"(/,E15.4,$)") Omega_p,Omega_g,SkinDepth,lambda_De
        write(*,"(/,A15,$)") "[v_Alfen]","[v_th]","[Cs]","[gyroradius]"
        write(*,"(/,E15.4,$)") v_Alfen,v_th,Cs,gyroradius
        write(*,"(/,A15,$)") "[Ma_Alfen]","[Ma_th]","[Ma_Cs]"
        write(*,"(/,E15.4,$)") v_unit/v_Alfen,v_unit/v_th,v_unit/Cs
        write(*,"(/,A15,$)") "[L_unit]","[v_unit]","[time_unit]"
        write(*,"(/,E15.4,$)") L_unit,v_unit,time_unit
        write(*,"(/,A15,$)") "[E_unit]","[B_unit]","[n_unit]"
        write(*,"(/,E15.4,$)") E_unit,B_unit,n_unit
    end if
    call initializeParallel()   ! Initialization.F90
    call initializeParticles()  ! Initialization.F90
    call initializeGrids()      ! Initialization.F90
    if(myid==1)then
        write(*,"(/,A15,$)") "[dt]","[dx]","[dy]","[Z]","[A]"
        write(*,"(/,F15.4,$)") dt,dx,dy,Z_avg,A_avg
        write(*,"(/,A15,$)") "[Nx]","[Ny]","[ncx]","[ncy]"
        write(*,"(/,I15,$)") Nx,Ny,ncx,ncy
        write(*,"(//)") 
    end if
    

    call dumpDatas()  ! Output.F90
    
! *******************************************************************
! Calculation
! *******************************************************************
    do while (RunTime<=TotalTime)
    ! **** Updating the Runing Time ********************
        ! Updating the Run Time of This Step
        call updateRunTime()  ! Physics.F90
    ! **************************************************
        !if(myid==1) write(*,*) RunTime
        if(UseCAMCL)then
            call useCAM_CL_Method()
        elseif(UseCNPPC)then
            call useCN_PPC_Method()
        else
            call useElectrostaticOnly()
        end if
    ! **** MPI Synchronization *************************
        ! Waiting for Each Other
        call mpi_barrier(mpi_comm_world,ierr)  ! MPI.mod
    ! **************************************************
        
    ! **** Diagnostics *********************************
        ! Output Datas
        if(RunTime>=DumpNumber*DumpPeriod)then
            call dumpDatas()  ! Output.F90
            if(myid==1) write(*,*) (DumpNumber-1)
        end if
    ! **************************************************
    end do

! *******************************************************************
! Finish
! *******************************************************************

    call releaseMemory()  ! Setup.F90
    if(UseTime) call recordEndTime()  ! Time.F90
    if(UseTime) call displayUsedTime()  ! Time.F90
    call mpi_finalize(ierr)  ! MPI.mod
end program Hybrid2D

! ******************************************************************************
! EOF
! ******************************************************************************